/**
 * 用户认证状态管理
 */
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import { ElMessage } from 'element-plus'
import {
  login,
  logout,
  register,
  refreshToken,
  getUserInfo,
  changePassword,
  resetPassword
} from '@/api/auth'
import type { User, LoginRequest, RegisterRequest } from '@/types'

export const useAuthStore = defineStore('auth', () => {
  // State
  const user = ref<User | null>(null)
  const accessToken = ref<string | null>(null)
  const refreshTokenValue = ref<string | null>(null)
  const loading = ref(false)

  // Getters
  const isAuthenticated = computed(() => !!accessToken.value && !!user.value)
  const userRole = computed(() => user.value?.role || null)
  const userName = computed(() => user.value?.username || '')
  const permissions = computed(() => {
    if (!user.value) return []

    // 根据角色返回权限
    const rolePermissions: Record<string, string[]> = {
      admin: [
        'user:read', 'user:write', 'user:delete',
        'question:read', 'question:write', 'question:delete',
        'exam:read', 'exam:write', 'exam:delete', 'exam:monitor',
        'grading:read', 'grading:write', 'grading:delete',
        'paper:read', 'paper:write', 'paper:delete',
        'system:read', 'system:write', 'system:delete'
      ],
      teacher: [
        'question:read', 'question:write',
        'exam:read', 'exam:write', 'exam:monitor',
        'grading:read', 'grading:write',
        'paper:read', 'paper:write'
      ],
      student: [
        'question:read',
        'exam:read', 'exam:take',
        'grading:read',
        'paper:read'
      ]
    }

    return rolePermissions[user.value.role] || []
  })

  // Actions
  const initializeAuth = async () => {
    const storedToken = localStorage.getItem('access_token')
    const storedRefreshToken = localStorage.getItem('refresh_token')

    if (storedToken && storedRefreshToken) {
      accessToken.value = storedToken
      refreshTokenValue.value = storedRefreshToken

      try {
        await fetchUserInfo()
      } catch (error) {
        // Token无效，清除认证信息
        clearAuth()
      }
    }
  }

  const fetchUserInfo = async () => {
    try {
      const response = await getUserInfo()
      user.value = response.data
    } catch (error) {
      throw error
    }
  }

  const loginAction = async (loginData: LoginRequest) => {
    loading.value = true
    try {
      const response = await login(loginData)
      const { access_token, refresh_token, user: userInfo } = response.data

      accessToken.value = access_token
      refreshTokenValue.value = refresh_token
      user.value = userInfo

      // 保存到localStorage
      localStorage.setItem('access_token', access_token)
      localStorage.setItem('refresh_token', refresh_token)
      localStorage.setItem('user_info', JSON.stringify(userInfo))

      ElMessage.success('登录成功')
      return response.data
    } catch (error: any) {
      ElMessage.error(error.message || '登录失败')
      throw error
    } finally {
      loading.value = false
    }
  }

  const registerAction = async (registerData: RegisterRequest) => {
    loading.value = true
    try {
      const response = await register(registerData)
      ElMessage.success('注册成功，请登录')
      return response.data
    } catch (error: any) {
      ElMessage.error(error.message || '注册失败')
      throw error
    } finally {
      loading.value = false
    }
  }

  const logoutAction = async () => {
    try {
      await logout()
    } catch (error) {
      console.error('Logout API error:', error)
    } finally {
      clearAuth()
      ElMessage.success('已退出登录')
    }
  }

  const clearAuth = () => {
    user.value = null
    accessToken.value = null
    refreshTokenValue.value = null

    // 清除localStorage
    localStorage.removeItem('access_token')
    localStorage.removeItem('refresh_token')
    localStorage.removeItem('user_info')
  }

  const refreshAccessToken = async () => {
    if (!refreshTokenValue.value) {
      throw new Error('No refresh token available')
    }

    try {
      const response = await refreshToken({ refresh_token: refreshTokenValue.value })
      const { access_token } = response.data

      accessToken.value = access_token
      localStorage.setItem('access_token', access_token)

      return access_token
    } catch (error) {
      // Refresh token失效，清除认证信息
      clearAuth()
      throw error
    }
  }

  const updateProfile = (userData: Partial<User>) => {
    if (user.value) {
      user.value = { ...user.value, ...userData }
      localStorage.setItem('user_info', JSON.stringify(user.value))
    }
  }

  const changePasswordAction = async (oldPassword: string, newPassword: string) => {
    loading.value = true
    try {
      await changePassword({ old_password: oldPassword, new_password: newPassword })
      ElMessage.success('密码修改成功')
    } catch (error: any) {
      ElMessage.error(error.message || '密码修改失败')
      throw error
    } finally {
      loading.value = false
    }
  }

  const resetPasswordAction = async (email: string) => {
    loading.value = true
    try {
      await resetPassword({ email })
      ElMessage.success('密码重置邮件已发送')
    } catch (error: any) {
      ElMessage.error(error.message || '密码重置失败')
      throw error
    } finally {
      loading.value = false
    }
  }

  // 权限检查方法
  const hasPermission = (permission: string) => {
    return permissions.value.includes(permission)
  }

  const hasRole = (role: string) => {
    return userRole.value === role
  }

  const hasAnyRole = (roles: string[]) => {
    return roles.includes(userRole.value || '')
  }

  const hasAllRoles = (roles: string[]) => {
    return roles.every(role => userRole.value === role)
  }

  return {
    // State
    user,
    accessToken,
    refreshTokenValue,
    loading,

    // Getters
    isAuthenticated,
    userRole,
    userName,
    permissions,

    // Actions
    initializeAuth,
    fetchUserInfo,
    loginAction,
    registerAction,
    logoutAction,
    clearAuth,
    refreshAccessToken,
    updateProfile,
    changePasswordAction,
    resetPasswordAction,
    hasPermission,
    hasRole,
    hasAnyRole,
    hasAllRoles
  }
})